package com.derbysoft.nuke.configkeeper.repository;

import com.amazonaws.services.dynamodbv2.datamodeling.*;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.derbysoft.nuke.configkeeper.domain.Config;
import com.derbysoft.nuke.configkeeper.domain.ConfigHistory;
import com.google.inject.Inject;

import java.util.List;
import java.util.stream.Collectors;

public class DefaultConfigRepository implements ConfigRepository {

    private DynamoDBMapper dynamoDBMapper;

    @Override
    public List<String> getSources() {
        PaginatedScanList<Config> paginatedScanList = dynamoDBMapper.scan(Config.class, new DynamoDBScanExpression());
        return paginatedScanList.stream().map(Config::getSource).collect(Collectors.toList());
    }

    @Override
    public void save(Config config) {
        dynamoDBMapper.save(config);
    }

    @Override
    public void saveHistory(ConfigHistory configHistory) {
        dynamoDBMapper.save(configHistory);
    }

    @Override
    public Config get(String source) {
        return dynamoDBMapper.load(Config.class, source);
    }

    @Override
    public List<ConfigHistory> findHistory(String source, Long timestamp) {
        timestamp = timestamp == null ? 0L : timestamp;
        Condition rangeKeyCondition = new Condition()
                .withComparisonOperator(ComparisonOperator.GT.toString())
                .withAttributeValueList(new AttributeValue().withN(timestamp.toString()));

        ConfigHistory configHistory = new ConfigHistory();
        configHistory.setSource(source);

        DynamoDBQueryExpression queryExpression = new DynamoDBQueryExpression()
                .withHashKeyValues(configHistory)
                .withRangeKeyCondition("timestamp", rangeKeyCondition);
        PaginatedQueryList paginatedQueryList = dynamoDBMapper.query(ConfigHistory.class, queryExpression);
        return paginatedQueryList;
    }

    @Inject
    public void setDynamoDBMapper(DynamoDBMapper dynamoDBMapper) {
        this.dynamoDBMapper = dynamoDBMapper;
    }
}
